package runesim.node;

import java.net.InetSocketAddress;
import org.apache.mina.common.IoAcceptor;
import org.apache.mina.integration.jmx.IoServiceManager;
import org.apache.mina.transport.socket.nio.SocketAcceptor;
import org.apache.mina.transport.socket.nio.SocketAcceptorConfig;
import runesim.node.model.World;
import runesim.node.net.ConnectionHandler;
import runesim.node.net.ConnectionThrottleFilter;

public class ServerSocketBinder {
	
	/* The game engine */
	private GameEngine engine;
	private IoAcceptor acceptor;
	private IoServiceManager serviceManager;
	private ConnectionHandler connectionHandler;
	private ConnectionThrottleFilter throttleFilter;
	
	public ServerSocketBinder() {
		if(World.getWorld() == null)
			throw new IllegalArgumentException("Cannot start server until World has been loaded.");
		engine = new GameEngine();
		acceptor = new SocketAcceptor();
		connectionHandler = new ConnectionHandler(engine);
	}
	
	public void start(int port) throws Exception {
		ServerSocketBinder.newThread(engine, "GameEngine");
		SocketAcceptorConfig sac = new SocketAcceptorConfig();
		sac.getSessionConfig().setTcpNoDelay(false);
		sac.setReuseAddress(true);
		sac.setBacklog(100);
		
		throttleFilter = new ConnectionThrottleFilter(0);
		sac.getFilterChain().addFirst("throttleFilter", throttleFilter);
		acceptor.bind(new InetSocketAddress(port), connectionHandler, sac);
	}
	
	public GameEngine getGameEngine() {
		return engine;
	}
	
	public static void newThread(Runnable r, String name) {
		Thread t = new Thread(group, r, name);
		t.start();
	}
	
	public IoServiceManager getServiceManager() {
		return serviceManager;
	}
	
	public ConnectionThrottleFilter getThrottleFilter() {
		return throttleFilter;
	}
	
	public void unbindPorts() throws Exception {
		Thread.sleep(200);
		acceptor.unbindAll();
		Thread.sleep(300);
	}
	
	private static ThreadGroup group;
}